package mrpanyu.guitool.base.util;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class CommonUtils {

	public static boolean isBlank(CharSequence text) {
		return text == null || text.toString().trim().length() == 0;
	}

	public static boolean isNotBlank(CharSequence text) {
		return !isBlank(text);
	}

	public static boolean isEmpty(CharSequence text) {
		return text == null || text.length() == 0;
	}

	public static boolean isNotEmpty(CharSequence text) {
		return !isEmpty(text);
	}

	public static String trim(String text) {
		return text != null ? text.trim() : null;
	}

	public static String trimToEmpty(String text) {
		return text != null ? text.trim() : "";
	}

	public static byte[] readFully(InputStream in) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buf = new byte[1024];
			int len = in.read(buf);
			while (len > 0) {
				baos.write(buf, 0, len);
				len = in.read(buf);
			}
			return baos.toByteArray();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static String readFully(Reader reader) {
		try {
			StringBuilder sb = new StringBuilder();
			char[] buf = new char[1024];
			int len = reader.read(buf);
			while (len > 0) {
				sb.append(buf, 0, len);
				len = reader.read(buf);
			}
			return sb.toString();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static byte[] readBytes(File f) {
		try (FileInputStream in = new FileInputStream(f)) {
			return readFully(in);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static String readString(File f, String encoding) {
		byte[] data = readBytes(f);
		return new String(data, Charset.forName(encoding));
	}

	public static List<String> readLines(File f, String encoding) {
		try (FileInputStream in = new FileInputStream(f);
				InputStreamReader insr = new InputStreamReader(in, encoding);
				BufferedReader reader = new BufferedReader(insr)) {
			List<String> lines = new ArrayList<>();
			String line = reader.readLine();
			while (line != null) {
				lines.add(line);
				line = reader.readLine();
			}
			return lines;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static void writeBytes(File f, byte[] data) {
		f.getParentFile().mkdirs();
		try (FileOutputStream out = new FileOutputStream(f)) {
			out.write(data);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static void writeString(File f, String text, String encoding) {
		f.getParentFile().mkdirs();
		try (FileOutputStream out = new FileOutputStream(f);
				OutputStreamWriter writer = new OutputStreamWriter(out, Charset.forName(encoding))) {
			writer.write(text);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static void writeLines(File f, List<String> lines, String encoding) {
		f.getParentFile().mkdirs();
		try (FileOutputStream out = new FileOutputStream(f);
				OutputStreamWriter writer = new OutputStreamWriter(out, Charset.forName(encoding));
				PrintWriter pw = new PrintWriter(writer)) {
			for (String line : lines) {
				pw.println(line);
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static void copyStream(InputStream in, OutputStream out) throws IOException {
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		while (len >= 0) {
			out.write(buf, 0, len);
			len = in.read(buf);
		}
	}

	public static void directoryScan(File file, Consumer<File> callback) {
		if (file == null || !file.exists()) {
			return;
		} else {
			callback.accept(file);
			if (file.isDirectory()) {
				File[] children = file.listFiles();
				for (File f : children) {
					directoryScan(f, callback);
				}
			}
		}
	}

	public static boolean makeParentDirs(String path) {
		return new File(path).getParentFile().mkdirs();
	}

	public static String getClipboardText() {
		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		Transferable trans = clipboard.getContents(null);
		if (trans == null) {
			return null;
		}
		try {
			DataFlavor df = DataFlavor.getTextPlainUnicodeFlavor();
			if (!trans.isDataFlavorSupported(df)) {
				return null;
			}
			try (Reader reader = df.getReaderForText(trans)) {
				String text = readFully(reader);
				return text;
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static void setClipboardText(String text) {
		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		StringSelection trans = new StringSelection(text);
		clipboard.setContents(trans, trans);
	}

	public static BufferedImage getClipboardImage() {
		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		Transferable trans = clipboard.getContents(null);
		if (trans == null) {
			return null;
		}
		try {
			if (!trans.isDataFlavorSupported(DataFlavor.imageFlavor)) {
				return null;
			}
			return (BufferedImage) trans.getTransferData(DataFlavor.imageFlavor);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static void setClipboardImage(BufferedImage img) {
		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		TransferableImage trans = new TransferableImage(img);
		clipboard.setContents(trans, trans);
	}

}
